package com.hlc.lv.common.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.codec.binary.Base64;

/**
 * @类名: SecurityUtil
 * @描述: 各种加密和解密算法 MD5、SHA、HMAC这三种加密算法，可谓是非可逆加密，就是不可解密的加密方法
 * 
 * @作者: zfh
 * @时间: 2016年6月27日 下午1:16:17
 */
public class SecurityUtil {

	private static String Algorithm = "DES";//// 定义 加密算法,可用 DES,DESede,Blowfish

	/*************************** DES **************************************/
	/**
	 * @方法名: encryptToDES
	 * @描述: DES加密处理
	 * @param content
	 * @param key
	 * @return String
	 */
	public static String encryptToDES(String content, String key) {
		try {
			SecureRandom random = new SecureRandom();
			DESKeySpec desKey = new DESKeySpec(key.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
			SecretKey securekey = keyFactory.generateSecret(desKey);
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
			byte[] result = cipher.doFinal(content.getBytes());

			String res = new String(result, "ISO-8859-1");

			return ByteStringHexUtil.stringToHexString(res);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 * 
	 * @param content
	 *            待解密内容
	 * @param key
	 *            解密的密钥
	 * @return
	 */
	public static String decryptByDES(String info, String key) {
		try {

			info = ByteStringHexUtil.hexStringToString(info);
			byte[] content = info.getBytes("ISO-8859-1");
			SecureRandom random = new SecureRandom();
			DESKeySpec desKey = new DESKeySpec(key.getBytes("ISO-8859-1"));
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
			SecretKey securekey = keyFactory.generateSecret(desKey);
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.DECRYPT_MODE, securekey, random);
			byte[] result = cipher.doFinal(content);
			return new String(result);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @方法名: byte2hex
	 * @描述: 二进制转化为十六进制
	 * @param b
	 * @return String
	 */
	public static String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1) {
				hs = hs + "0" + stmp;
			} else {
				hs = hs + stmp;
			}
		}
		return hs.toUpperCase();
	}

	/**
	 * @方法名: hex2byte
	 * @描述: 十六进制转化为二进制
	 * @param hex
	 * @return byte[]
	 */
	public static byte[] hex2byte(String hex) {
		System.out.println("" + hex);
		byte[] ret = new byte[8];
		byte[] tmp = hex.getBytes();
		for (int i = 0; i < 8; i++) {
			ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
		}
		return ret;
	}

	/**
	 * @方法名: uniteBytes
	 * @描述: 将两个ASCII字符合成一个字节； 如："EF"--> 0xEF
	 * @param src0
	 * @param src1
	 * @return byte
	 */
	public static byte uniteBytes(byte src0, byte src1) {
		byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 })).byteValue();
		_b0 = (byte) (_b0 << 4);
		byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 })).byteValue();
		byte ret = (byte) (_b0 ^ _b1);
		return ret;
	}

	/*************************** MD5 **************************************/
	/**
	 * @方法名: encryptToMD5
	 * @描述: 进行md5的加密
	 * @param info
	 * @return String
	 */
	public static String encryptToMD5(String info) {
		byte[] digesta = null;
		try {
			// 得到一个md5的消息摘要
			MessageDigest alga = MessageDigest.getInstance("MD5");
			// 添加要进行计算摘要的信息
			alga.update(info.getBytes());
			// 得到该摘要
			digesta = alga.digest();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		// 将摘要转为字符串
		String rs = byte2hex(digesta);
		return rs;
	}

	/*************************** SHA **************************************/
	/**
	 * @方法名: encryptToSHA
	 * @描述: 进行SHA的加密
	 * @param info
	 * @return String
	 */
	public static String encryptToSHA(String info) {
		byte[] digesta = null;
		try {
			// 得到一个SHA-1的消息摘要
			MessageDigest alga = MessageDigest.getInstance("SHA-1");
			// 添加要进行计算摘要的信息
			alga.update(info.getBytes());
			// 得到该摘要
			digesta = alga.digest();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		String rs = byte2hex(digesta);
		return rs;
	}

	/********************* BASE64 加密 **************************************/
	/**
	 * @方法名: encryptBASE64
	 * @描述: 使用Base64加密
	 * @param plainText
	 * @return String
	 */
	public static String encryptBASE64(String plainText) {
		byte[] b = plainText.getBytes();
		Base64 base64 = new Base64();
		b = base64.encode(b);
		String s = new String(b);
		return s;
	}

	/**
	 * @方法名: decryptBASE64
	 * @描述: 使用Base64解密
	 * @param encodeStr
	 * @return String
	 */
	public static String decryptBASE64(String encodeStr) {
		byte[] b = encodeStr.getBytes();
		Base64 base64 = new Base64();
		b = base64.decode(b);
		String s = new String(b);
		return s;
	}

	/**
	 * @方法名: encryptBASE64ToHex
	 * @描述: 进行base64加密操作
	 * @param string
	 * @return String
	 */
	public static String encryptBASE64ToHex(String string) {
		String s = encryptBASE64(string);

		return ByteStringHexUtil.stringToHexString(s);
	}

	/**
	 * @方法名: decrpyHexStringBASE64ToString
	 * @描述: 进行base64解码操作
	 * @param string
	 * @return String
	 */
	public static String decrpyHexStringBASE64ToString(String string) {

		String info = ByteStringHexUtil.hexStringToString(string);

		return decryptBASE64(info);
	}

	public static void main(String[] args) throws Exception {
		
		  String str = "zhangfuhong";
		  System.out.println(encryptToMD5("admin"));
		  System.out.println(encryptBASE64ToHex(str.trim()));
		  System.out.println(decrpyHexStringBASE64ToString(encryptBASE64ToHex(
		  str.trim())));
		 

		String content = "zhangfuhong";  
        // 密码长度必须是8的倍数  
        String password = "12123213123";  
        System.out.println("密　钥：" + password);  
        System.out.println("加密前：" + content);  
        String result = encryptToDES(content, password);  
        System.out.println("密文"+result);
      //  System.out.println("加密后：" + new String(result,"UTF-8"));
     //   System.out.println("加密后十六进制：" +ByteStringHexUtil.stringToHexString( new String(result)));
     //   System.out.println(ByteStringHexUtil.stringToHexString(new String(result)));
     //   System.out.println(ByteStringHexUtil.hexStringToString(ByteStringHexUtil.stringToHexString(new String(result))));
    //  System.out.println("解密前"+ByteStringHexUtil.hexStringToString(ByteStringHexUtil.stringToHexString( new String(result))));
        String decryResult = decryptByDES(result, password);  
        System.out.println("解密后：" + decryResult);  

	}
}
